<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>生成名片</title>
    <link rel="stylesheet" href="css/index.css" />
</head>
<body>
    <div class="box">
        <!-- 左边 -->
        <div id="container">
            <div class="container-border">
                    <img id="img" style="width: 200px;height: 200px;" src="img/t.png" />
                    <div class="detail">
                        <span class="nickname">张三</span>
                        <span class="job">WEB前端工程师</span>
                    </div>
                    <div class="introduce">3年ToB类产品开发经验，经常跨部门沟通，能够站在产品角度考虑问题。
                        较强的执行力，能推动和协同其他人实现需求落地，并取得预期效果。
                        较强的产品思维，多次协助pm打造出优秀的项目。</div>
            </div>
        </div>

        <!-- 右边 -->
        <div class="rightConent">
            <div>
                <input class="file-input" type="file" name="avatar" />
                <div class="file-font">上传头像</div>
            </div>

            <div class="inputBox">
                <input name="nickname" type="text" value="张三" placeholder="请输入昵称" required />
                <input name="job" type="text" value="WEB前端工程师" placeholder="请输入职位" required />
                <input name="introduce" type="text" value="3年ToB类产品开发经验，经常跨部门沟通，能够站在产品角度考虑问题。 较强的执行力，能推动和协同其他人实现需求落地，并取得预期效果。 较强的产品思维，多次协助pm打造出优秀的项目。" placeholder="请输入个人简介" required />
                <input name="picname" type="text" value="" placeholder="生成名片图片名称" />
            </div>
            
            <div id="save">保存图片</div>
        </div>
    </div>
</body>
</html>
<script src="./js/jquery.min.js"></script>

<!-- 将html网页转换为图片 -->
<script src="./js/html2canvas.min.js"></script>

<script>
    //输入框绑定输入事件
    $("input[name=nickname],input[name=job],input[name=introduce]").on('input', function(){
        //获取元素的源生属性
        var name = $(this).prop('name')
        var value = $.trim($(this).val())
        
        //修改左侧预览的span元素
        $(`.${name}`).text(value)
    })

    //文件上传预览 文件选择被改变了
    $('input[name=avatar]').change(function(){
        //获取到文件
        var avatar = this.files[0] ? this.files[0] : undefined

        //判断是否存在
        if(!avatar)
        {
            alert('请上传头像')
            return;
        }

        //读取文件
        var reader = new FileReader()

        //再去读取文件后并返回一个本地base64的数据结构
        reader.readAsDataURL(avatar)

        //出发读取器的事件 完成事件
        reader.onload = e => $("#img").prop('src', e.target.result)
    })
    
    //点击保存按钮
    $("#save").click(function(){
        //获取输入框的内容
        var nickname = $.trim($('input[name=nickname]').val())
        var job = $.trim($('input[name=job]').val())
        var introduce = $.trim($('input[name=introduce]').val())

        //对内容做判断
        if(!nickname)
        {
            alert('请输入昵称')
            $('input[name=nickname]').focus() //让他产生焦点
            return;
        }

        if(!job)
        {
            alert('请输入职位')
            $('input[name=job]').focus() //让他产生焦点
            return;
        }

        if(!introduce)
        {
            alert('请输入简介')
            $('input[name=introduce]').focus() //让他产生焦点
            return;
        }

        //获取保存的文件名称
        var picname = $.trim($('input[name=picname]').val())
        picname = picname ? `${picname}.jpg` : 'card.jpg'
        

        //获取盒子的宽高
        var width = $("#container").width()
        var height = $("#container").height()

        //创建画布DOM元素
        var canvas = document.createElement('canvas')

        //构建2D画布
        var ctx = canvas.getContext('2d')

        //获取缩放比率
        let scale = GetPixelRatio(ctx);

        //设置画布宽高和缩放比率
        canvas.width = width * scale
        canvas.height = height * scale
        canvas.style.width = `${width * scale}px`
        canvas.style.height = `${height * scale}px`

        //设置画布的缩放比率
        ctx.scale(scale, scale)
        

        //设置准备截图的参数
        let opts = {
            scale: scale,
            canvas: canvas,
            width: width,
            height: height,
            dpi: window.devicePixelRatio
        };
        
        //调用插件
        html2canvas($("#container").get(0), opts).then(function (result) {
            // Canvas 2D API 用来设置图片是否平滑的属性，true表示图片平滑（默认值），false表示图片不平滑
            ctx.imageSmoothingEnabled = false;
            ctx.webkitImageSmoothingEnabled = false;
            ctx.msImageSmoothingEnabled = false;
            ctx.imageSmoothingEnabled = false;

            //将图片生成url地址信息(base64格式)
            var url = result.toDataURL('image/jpeg', 1.0)

            //预览效果
            // $("body").append(`<img src="${url}">`)

            //下载图片
            DataURIToBlob(picname, url)
        })

        //下载
        let DataURIToBlob = (picname, url) => 
        {
            //base64 转换为 blob格式
            let binStr = atob(url.split(',')[1])
            let len = binStr.length
            
            //构建原始数据 二进制的数据结构
            arr = new Uint8Array(len);  //申请内存空间

            //将内容写到内存空间去
            for(let i = 0; i < len; i++)
            {
                arr[i] = binStr.charCodeAt(i);
            }

            //转换为文件的blob对象
            var blob = new Blob([arr]) 

            //通过点击链接下载文件
            var download = $("<a>")
                .prop('href', URL.createObjectURL(blob)) //将blob对象生成一个url链接
                .prop('download', picname)  //下载的保存文件名
                .text('下载链接')
                .appendTo("body")
                .on('click', function(){
                    if (navigator.msSaveBlob) 
                    {
                        return navigator.msSaveBlob(blob, picname);
                    }
            })

            //模拟点击
            download[0].click()

            //将a元素删除
            download.remove()
        }
    })




    // 获取设备的PixelRatio 设备的缩放比率
    // https://blog.csdn.net/xueli_2017/article/details/91492971
    let GetPixelRatio = function (context) 
    {
        if(context)
        {
            let backingStore = context.backingStorePixelRatio ||
                context.webkitBackingStorePixelRatio ||
                context.mozBackingStorePixelRatio ||
                context.msBackingStorePixelRatio ||
                context.oBackingStorePixelRatio ||
                context.backingStorePixelRatio || 0.5;
            return (window.devicePixelRatio || 0.5) / backingStore;
        }
    };











</script>